/*
2012-08-15
 1. 增加 setBook(Collection) method 但暫不開放。
 2. 增加 resetTableCache(TableCache) method 此元件設計仍以 TableCache 為主。
*/

package idv.jieh.commons.book;

/**
 * <p>Title: 藍色小惡魔的系統</p>
 * <p>
 * 如果你使用 <code>EasyBook</code> 物件的話，那 <code>QueryBook</code>
 * 的許多方法你並不需要去關心，因為所有的事情都將會由分頁架構中的方法解決。
 * </p>
 * <p>
 * 設定後的第一次使用必須呼叫 QueryBook <u>next()</u> method
 * ，進行翻頁的動作，之後就可以呼叫 <code>getQueryPage</code> 取得目前的頁面物件。
 * </p>
 * @author Jieh
 * @version 1.0
 */

public class QueryBook {

  // *************************** 以上為施工區 ***************************

  private idv.jieh.commons.sql.TableCache book = null;

  // 一頁顯示幾筆資料。
  private int member = 10;
  // 頁碼，紀錄目前翻到第幾頁了
  private int pagination = 0;
  // 紀錄總頁數
  private int totalPage;
  // 紀錄總筆數
  private int totalRow;

  /**
   * 建構子。
   * @param tc TableCache Object。
   */
  public QueryBook(idv.jieh.commons.sql.TableCache tc){
    book = tc;
    this.reset();
  }

  /**
   * 取回 <code>TableCache</code>。
   * @return TableCache
   */
  public idv.jieh.commons.sql.TableCache getTableCache(){
    return book;
  }

  /**
   * 詢問目前是否有任何物件在 <code>QueryBook</code> 之內。
   * @return true：沒有任何物件在裡面，也就是說大小為零；false：相反。
   */
  public boolean isEmpty(){
    return book.isEmpty();
  }

//  public idv.jieh.commons.sql.RowCache remove(int idx){
//
//  }

  /**
   * 取得目前翻到的頁面。<p>
   * @return QueryPage Object。
   */
  public QueryPage getQueryPage() {
    // 沒有資料
    if (book.size() == 0) return new QueryPage(book, 1, member);

    int s = (pagination - 1) * member;
    int e = Math.min(s + member, book.size());
    return new QueryPage(book.subList(s, e), pagination, member);
  }

  /**
   * 翻到下一頁。<p>
   * @return true：已經成功翻到下一頁了；false：已經是最後一頁。
   */
  public boolean next() {
    if (pagination < totalPage) {
      pagination++;
      return true;
    }
    return false;
  }

  /**
   * 翻回上一頁。<p>
   * @return true：已經成功翻回上一頁；false：已經是第一頁。
   */
  public boolean previous() {
    if (pagination > 1) {
      pagination--;
      return true;
    }
    return false;
  }

  /**
   * 重設 Book(把書蓋上)。<p>
   * 當書本初始化時或者每一頁顯示的筆數被變動，這個方法就會被呼叫。
   * 也就是要把書本由第一頁開始。
   * 同時重新計算總頁數。
   */
  private void reset() {
      totalRow = book.size();

      if(totalRow == 0) return;
      pagination = 0;

      totalPage = totalRow / member;
      // 以下怪怪的 要再研究
      if (totalPage == 0) {
        totalPage = 1;
        return;
      }

      int mod = totalRow % member;
      if (mod != 0) {
        totalPage++;
      }
  }

  /**
   * 是否需要顯示下一頁的按鈕。<p>
   * 若還有下一頁，所以需要顯示按鈕；若已經是最後一頁，則不顯示。<br>
   * @return true：顯示按鈕；false：不顯示按鈕。
   */
  public boolean showNextButton() {
    boolean r = false;
    if (this.pagination < this.totalPage) {
      r = true;
    }
    return r;
  }

  /**
   * 是否需要顯示下一頁的按鈕。<p>
   * @return true：還有下一頁所以需要顯示按鈕；false：相反。
   */
  public boolean showPreviousButton() {
    return pagination > 1;
  }

  /**
   * 設定每頁顯示的筆數。<p>
   * @param member 筆數。
   */
  public void setMember(int member) {
    this.member = member;
    this.reset();
  }

  /**
   * 取得目前設定每頁顯示的筆數。<p>
   * @return 每頁顯示的筆數。
   */
  public int getMember() {
    return member;
  }

  /**
   * 設定頁碼。<p>
   * @param pagination 選擇的頁碼。
   */
  public void setPagination(int pagination) {
    this.pagination = pagination;
  }

  /**
   * 取得目前的頁碼。<p>
   * @return 頁碼。
   */
  public int getPagination() {
    return pagination;
  }

  /**
   * 取得總頁數。<p>
   * @return 總頁數。
   */
  public int getTotalPage() {
    return totalPage;
  }

  /**
   * 取得總筆數。<p>
   * @return 總筆數。
   */
  public int getTotalRow() {
    return totalRow;
  }


  /**
   * 以 <code>idv.jieh.commons.sql.TableCache</code> 重建分頁元件。<p>
   * @param tc TableCache
   */
  public void resetTableCache(idv.jieh.commons.sql.TableCache tc) {
    this.book = tc;
    this.setBook((java.util.Collection)tc);
  }


  /**
   * 以 <code>java.util.Collection</code> 重建分頁元件。<p>
   * 搬過來還沒驗證過，因為初次的建構方法和上一代不同了，再仔細規劃確認功用後再開放。
   * @param c Collection
   */
  private void setBook(java.util.Collection c) {
    book.clear();
    book.addAll(c);
    this.reset();
  }


} // end class QueryBook
